package org.edu.page;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

public class DateUtils
{
    public static final String DATE_PATTERN = "yyyy-MM-dd";
    public static String DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS_SSS = "yyyyMMddHHmmssSSS";
    public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static String[][] regularExp = { { "\\d{4}-((([0][1,3-9]|[1][0-2]|[1-9])-([0-2]\\d|[3][0,1]|[1-9]))|((02|2)-(([1-9])|[0-2]\\d)))\\s+([0,1]\\d|[2][0-3]|\\d):([0-5]\\d|\\d):([0-5]\\d|\\d)", "yyyy-MM-dd HH:mm:ss" }, { "\\d{4}-((([0][1,3-9]|[1][0-2]|[1-9])-([0-2]\\d|[3][0,1]|[1-9]))|((02|2)-(([1-9])|[0-2]\\d)))", "yyyy-MM-dd" }, { "\\d{4}((([0][1,3-9]|[1][0-2]|[1-9])([0-2]\\d|[3][0,1]|[1-9]))|((02|2)(([1-9])|[0-2]\\d)))([0,1]\\d|[2][0-3])([0-5]\\d|\\d)([0-5]\\d|\\d)\\d{1,3}", DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS_SSS } };

    public static String format(Date date)
    {
        return format(date, "yyyy-MM-dd");
    }

    public static String getCurDate()
    {
        return format(new Date(), "yyyy-MM-dd");
    }

    public static String format(Date date, String pattern)
    {
        if (date != null)
        {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    public static String timeToStr(Long time, String pattern)
    {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        if (time.toString().length() < 13) {
            time = Long.valueOf(time.longValue() * 1000L);
        }
        Date date = new Date(time.longValue());
        String value = dateFormat.format(date);
        return value;
    }

    public static long strToTime(String timeStr)
    {
        Date time = strToDate(timeStr);
        return time.getTime() / 1000L;
    }

    public static Date strToDate(String strDate)
    {
        try
        {
            String strType = getDateFormat(strDate);
            SimpleDateFormat sf = new SimpleDateFormat(strType);
            return new Date(sf.parse(strDate).getTime());
        }
        catch (Exception e) {}
        return null;
    }

    public static String getDateFormat(String date_str)
    {
        String style = null;
        if (StringUtils.isEmpty(date_str)) {
            return null;
        }
        boolean b = false;
        for (int i = 0; i < regularExp.length; i++)
        {
            b = date_str.matches(regularExp[i][0]);
            if (b) {
                style = regularExp[i][1];
            }
        }
        if (StringUtils.isEmpty(style)) {}
        return style;
    }

    public static Date convertStringToDate(String dateStr)
    {
        Date resultDate = null;
        try
        {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            resultDate = sdf.parse(dateStr);
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        return resultDate;
    }

    public static String getCurTimeStamp()
    {
        return format(new Date(), DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM_SS_SSS);
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime)
    {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        Date date = Date.from(zdt.toInstant());
        return date;
    }

    public static LocalDate date2localDate(Date date)
    {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();

        return instant.atZone(zoneId).toLocalDate();
    }

    public static LocalDateTime date2localDateTime(Date date)
    {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();

        return LocalDateTime.ofInstant(instant, zoneId);
    }

    public static Date getTimesmorning()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(11, 0);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getYesterdaymorning()
    {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(getTimesmorning().getTime() - 86400000L);
        return cal.getTime();
    }

    public static Date getWeekFromNow()
    {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(getTimesmorning().getTime() - 604800000L);
        return cal.getTime();
    }

    public static Date getTimesnight()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(11, 24);
        cal.set(13, 0);
        cal.set(12, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getTimesWeekmorning()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        cal.set(7, 2);
        return cal.getTime();
    }

    public static Date getTimesWeeknight()
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getTimesWeekmorning());
        cal.add(7, 7);
        return cal.getTime();
    }

    public static Date getTimesMonthmorning()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        cal.set(5, cal.getActualMinimum(5));
        return cal.getTime();
    }

    public static Date getTimesMonthnight()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        cal.set(5, cal.getActualMaximum(5));
        cal.set(11, 24);
        return cal.getTime();
    }

    public static Date getLastMonthStartMorning()
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getTimesMonthmorning());
        cal.add(2, -1);
        return cal.getTime();
    }

    public static Date getCurrentQuarterStartTime()
    {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(2) + 1;
        SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Date now = null;
        try
        {
            if ((currentMonth >= 1) && (currentMonth <= 3)) {
                c.set(2, 0);
            } else if ((currentMonth >= 4) && (currentMonth <= 6)) {
                c.set(2, 3);
            } else if ((currentMonth >= 7) && (currentMonth <= 9)) {
                c.set(2, 4);
            } else if ((currentMonth >= 10) && (currentMonth <= 12)) {
                c.set(2, 9);
            }
            c.set(5, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return now;
    }

    public static Date getCurrentQuarterEndTime()
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getCurrentQuarterStartTime());
        cal.add(2, 3);
        return cal.getTime();
    }

    public static Date getCurrentYearStartTime()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        cal.set(5, cal.getActualMinimum(1));
        return cal.getTime();
    }

    public static Date getCurrentYearEndTime()
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getCurrentYearStartTime());
        cal.add(1, 1);
        return cal.getTime();
    }

    public static Date getLastYearStartTime()
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getCurrentYearStartTime());
        cal.add(1, -1);
        return cal.getTime();
    }

    public static String timeDiff(String pBeginTime, String pEndTime)
            throws Exception
    {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        Long beginL = Long.valueOf(format.parse(pBeginTime).getTime());
        Long endL = Long.valueOf(format.parse(pEndTime).getTime());
        Long day = Long.valueOf((endL.longValue() - beginL.longValue()) / 86400000L);
        Long hour = Long.valueOf((endL.longValue() - beginL.longValue()) % 86400000L / 3600000L);
        Long min = Long.valueOf((endL.longValue() - beginL.longValue()) % 86400000L % 3600000L / 60000L);
        return day + "天" + hour + "时" + min + "分";
    }
}
